import { ScriptExecution, ExecutionConfig } from "engines";
import { Disposable, InjectionToken, scoped, Lifecycle } from "tsyringe";
@scoped(Lifecycle.ContainerScoped)
export class ScriptManager implements Disposable {
    scriptExecutions: Map<InjectionToken<any>, ScriptExecution> = new Map();
    constructor() { }
    start(name: string, script: string, config?: ExecutionConfig) {
        this.stop(name)
        const scriptExecution = engines.execScript(name, script, config)
        this.scriptExecutions.set(name, scriptExecution)
    }
    main(path: string, name: string = 'MAIN', config?: ExecutionConfig) {
        this.stop(name)
        const scriptExecution = engines.execScriptFile(path, config)
        sleep(500)//等待脚本运行
        this.scriptExecutions.set(name, scriptExecution)
    }
    emit(type: InjectionToken<any>, payload: any) {
        const execution = this.scriptExecutions.get(type)
        if (execution) {
            const eng = execution.getEngine();
            if (eng) {
                eng.emit(`MESSAGE`, payload)
            } else {
                console.log('get engine fail')
            }
        }
    }
    watchMain(fn: (script: ScriptManager) => void) {
        while (true) {
            const execution = this.scriptExecutions.get("MAIN")
            if (!execution) {
                fn(this)
                sleep(10 * 1000)
            } else {
                const eng = execution?.getEngine()
                if (eng && eng.isDestroyed()) {
                    fn(this)
                }
                sleep(10 * 1000)
            }
        }
    }
    stop(name: string) {
        const execution = this.scriptExecutions.get(name)
        if (execution) {
            const eng = execution.getEngine()
            if (eng) {
                if (!eng.isDestroyed()) {
                    eng.forceStop()
                    this.scriptExecutions.delete(name)
                }
            }
        }
    }
    dispose(): void | Promise<void> {
        this.scriptExecutions.forEach(it => {
            const eng = it.getEngine();
            if (eng && !eng.isDestroyed()) {
                eng.forceStop()
            }
        })
        this.scriptExecutions.clear()
    }
}